/*	Nama file		: ListOfString.c
	Deskripsi		: Body type dan prototype primitf type List. List direpresentasi dengan pointer, First dinyatakan secara eksplisit
	Nama pembuat	: Ni Made Satvika Iswari/23512077
	Hari / Tanggal	: Selasa, 25 September 2012
*/

#include "ListOfString.h"

/** PROTOTYPE **/
/** Test List Kosong **/
boolean ListEmpty (ListStr L)
/* Mengirimi true jika list kosong */
{
	return (First(L)==Nil);
}
          
/** Pembuatan List Kosong **/
void CreateList (ListStr *L)
/* Proses : Membuat list kosong */
/* I.S : sembarang */
/* F.S : Terbentuk list kosong */
{
	First(*L)=Nil;
}

/** Pembuatan List dari Deretan String **/
ListStr MakeListfromStr(char str[])
/* Mengembalikan ListStr dari deretan string */
{
	/* Kamus Lokal */
	ListStr L;
	char delims[] = ",";
	char *name = NULL;
	
	/* Algoritma */
	CreateList(&L);
	name = strtok( str, delims );
	while( name != NULL ) {
		InsVLast(&L, name);
		name = strtok( NULL, delims );
	}
	return L;
}
      
//** Manajemen Memori **/
address Alokasi (infotype X)
/* Mengirimkan address hasil alokasi sebuah elemen */
/* Jika alokasi berhasil, maka address tidak Nil, dan misalnya menghasilkan P, maka info(P)=X, Next(P)=Nil */
/* Jika alokasi gagal, mengirimkan Nil */
{
	//Kamus Lokal
	address P;

	//Algoritma
	P=(address) malloc (sizeof(ElmtListStr));
	Info(P) = (char*) malloc ((MAX_CHAR_LIST) * sizeof(char));
	if (P!=Nil){ //Alokasi berhasil
		strcpy(Info(P),X);
		Next(P)=Nil;
	}
	return (P);
}
       
void Dealokasi (address P)
/* Proses : melakukan dealokasi/pengembalian address P */
/* I.S : P terdefinisi */
/* F.S : P dikembalikan ke sistem */
{
	free(P);
}

/** Pencarian Sebuah Elemen List **/
address Search (ListStr L, infotype X)
/* Mencari apakah ada elemen list dengan info(P)=X */
/* Jika ada, mengirimkan address elemen tersebut */
/* Jika tidak ada, mengirim Nil */
{
	//Kamus Lokal
	address Pt;

	//Algoritma
	Pt=First(L);
	while((Info(Pt)!=X) && (Next(Pt)!=Nil)){
		Pt=Next(Pt);
	}

	if (Info(Pt)!=X)
		return Nil;    //tidak ditemukan
	else
		return Pt;    //ditemukan
}
       
boolean FSearch(ListStr L, address P)
/* Mencari apakah ada elemen list yang beralamat P */
/* Mengirimkan true jika ada, false jika tidak ada */
{
	//Kamus Lokal
	address Pt;

	//Algoritma
	Pt=First(L);
	while((Pt!=P) && (Next(Pt)!=Nil)){
		Pt=Next(Pt);
	}

	if (Pt!=P){
		return false;		//elemen list tidak ditemukan
	}else{
		return true;        //elemen list ditemukan
	}
}
 
/** PRIMITIF BERDASARKAN NILAI **/
/** Penambahan Elemen **/
void InsVFirst (ListStr *L, infotype X)
/* Proses : Melakukan alokasi sebuah elmen dan menambahkan elmen pertama dengan nilai X jika alokasi berhasil
            Jika alokasi gagal : I.S = F.S */
/* I.S : L mungkin kosong */
/* F.S :  X ditambahkan sebagai elemen pertama L */
{
	/* Kamus Lokal */
	address P;
	
	/* Algoritma */
	P = Alokasi(X);
	if (P != NULL){
		InsertFirst(L,P);
	}
}
          
void InsVLast(ListStr *L, infotype X)
/* I.S L mungkin kosong */
/* F.S X ditambahkan sebagai elemen terakhir L */
/* Proses : melakukan alokasi sebuah elemen dan menambahkan elmen list di akhir:
            elemen terakhir yang baru bernilai X jika alokasi berhasil
            Jika alokasi gagal : I.S = F.S */
{
	/* Kamus Lokal */
	address P;
	
	/* Algoritma */
	P = Alokasi(X);
	if (P != NULL){
		InsertLast(L,P);
	}
 }
      
/** PRIMITIF BERDASARKAN ALAMAT **/
/** Penambahan Elemen Berdasarkan Alamat **/
void InsertFirst(ListStr *L, address P)
/* Proses : Menambahkan elemen ber-address P sebagai elemen pertama */
/* I.S : Sembarang, P sudah dialokasi */
/* F.S : P menjadi elemen pertama list */
{
	Next(P) = First(*L);
	First(*L) = P;
}

void InsertAfter(ListStr *L, address P, address Prec)
/* Proses : Insert P sebagai elemen sesudah elemen beralamat Prec */
/* I.S : Prec pastilah elemen list dan bukan elemen terakhir, P sudah dialokasi */
/* F.S : P menjadi elemen sesudah elemen beralamat Prec */
{
	Next(P) = Next(Prec);
	Next(Prec) = P;
}
    
void InsertLast(ListStr *L, address P)
/* Proses : P ditambahkan sebagai elemen terakhir yang baru */
/* I.S : sembarang, P sudah dialokasi */
/* F.S : P menjadi elemen terakhir yang baru */
{
	/* Kamus Lokal */
	address Last;
	
	/* Algoritma */
	if (First(*L) == NULL){
		InsertFirst(L, P);
	}else{
		Last = First(*L);
		while (Next(Last) != NULL){
			Last = Next(Last);
		}
		InsertAfter(L,P,Last);
	}
 }

 /** Operator Baca/Tulis **/
void BacaList (ListStr *L)
/* I.S. Sembarang */
/* F.S. L terdefinisi */
/* Proses : Membaca komponen List dari masukan pengguna */
{
	/* Kamus Lokal */
	char* name;
	char* tmp;	
	
	/* Algoritma */
	CreateList(L);
	name = (char*) malloc (MAX_CHAR_LIST * sizeof(char));
	printf("  Masukkan nama, akhiri dengan # : ");
	scanf(" %[^\n]s",name);
	
	while (strcmp(name, "#") != 0){
		InsVLast(L, name);
		printf("  Masukkan nama, akhiri dengan # : ");
		scanf(" %[^\n]s",name);
	}
}

void TulisList(ListStr L)
/* I.S. L terdefinisi */
/* F.S. Nilai L ditulis ke layar beserta komponen-komponennya */
/* Proses : Menulis nilai setiap komponen L ke layar */
{
	/* Kamus Lokal */
	address P;
	
	/* Algoritma */
	printf("List nama\t: %s", ListStrToString(L));
}

char* ListStrToString(ListStr L)
/* Mengembalikan list nama dengan dipisahkan dengan tanda koma */
{
	/* Kamus Lokal */
	char *tmp;
	address P;
	
	/* Algoritma */
	tmp = (char*) malloc (MAX_CHAR_LIST * sizeof(char));
	if (First(L) == NULL){
		strcpy(tmp, "kosong.");
	}else{
		P = First(L);
		strcpy(tmp, Info(P));
		while (Next(P) != NULL){
			P = Next(P);
			strcat(tmp, ",");
			strcat(tmp, Info(P));
		}
	}
	return tmp;
}



